/**
* C Rush OS
* 60-330 Final Assignment
* Submitted by:
*	Joseph Greaves
*	Benjamin Iannetta
*	Paul Wolak
*	
* Memory:
*	defines a simulated, 4gb memory block used only
*	by processes created.
*/

//imports
import java.util.Stack;

public class Memory{
	//Local Variables
	private int [] frames;
	private Stack<Integer> freeFrameList;
	private int currProcess;
	
	//Constructor
	public Memory(){
		frames = new int [524288];
		freeFrameList = new Stack<Integer>();
		
		for(int i = 0; i < frames.length; i++){
			freeFrameList.push(i);
		}
	}
	
	//Methods
	
	//Switches the active process
	public boolean switchProcess(int newProcess){
		//prevProcess = currProcess;
		currProcess = newProcess;
		return true;
	}
	
	public int[] addProcess(Process p){
		int tempPageTable [] = p.pcb.getPageTable();
		int frameNo;
	
		if(tempPageTable.length > freeFrameList.size()){
			System.out.println("Memory not currently available");
			return null;
		}
		
		for(int i = 0; i < tempPageTable.length; i++){
			//Get next free frame and remove it from freeFrameList
			frameNo = freeFrameList.pop().intValue();
			
			//Add process to the free frame
			frames[frameNo] = p.getPno();
			
			//Add frame to Page Table
			tempPageTable[i] = frameNo;
		}
		Kernel.writeToLog("Process "+p.getPno()+" added to memory successfully");
		System.out.println("Process "+p.getPno()+" added to memory successfully");
		/*
		for(int i = 0; i < tempPageTable.length; i++){
			System.out.println("Process "+p.getPno()+" pageTable["+i+"] = "+tempPageTable[i]);
		}*/
		return tempPageTable;
	}
	

	
	public void removeProcess(Process p){
		for(int i : p.pcb.getPageTable()){
			frames[i] = -1;
			freeFrameList.push(i);
		}
	}
	
	
	//Calls the specified process' execution method
	public boolean executeProcess(int process){
		//Frames[i].execute();
		return true;
	}
	
	public int totalMemory()
	{
		return 524288*8;
	}
	
	public int isMemoryAvailable(int size){
		int pagesRequired = size/8;
		if(size%8 != 0)
			pagesRequired++;
			//Kernel.writeToLog("pages required =" +pagesRequired+ " Free frame list size =" + freeFrameList.size());
		if(pagesRequired > frames.length){
			Kernel.writeToLog("Memory will never be available");
			System.out.println("Memory will never be available");
			return -2;
		}		

		if(pagesRequired > freeFrameList.size()){
			Kernel.writeToLog("Memory is not currently available");
			System.out.println("Memory is not currently available");
			return -1;
		}
		Kernel.writeToLog("Memory is currently available");
		System.out.println("Memory is currently available");
		return 0;
	}

	public int memoryAvailable(){
		int size = freeFrameList.size()*8;
		Kernel.writeToLog("Current memory available is: " + size);
		System.out.println("Current memory available is: " + size);
		return size;
	}
}//end Memory

